home *** CD-ROM | disk | FTP | other *** search
-
-
- Dear C++ programmer,
-
-
- Thank you for downloading csteam. The StreamableClass class
- provides a base class for a polymorphic cluster of
- streamable classes! In other words, any class derived from
- the StreamableClass can be stored on a stream and
- subsequently loaded from the stream later. All such classes
- can be stored in any order and/or mix on the same stream.
-
- The inspiration for my StreamableClass comes from Borland's
- TurboVision for Turbo Pascal. A TurboVision for BC++ has
- been hinted at by Borland but cstream allows you to stream
- classes NOW without the whole TurboVision tool. Not to
- mention it's FreeWare.
-
-
-
- Getting Started
- ===============
-
- Copy cstream.hpp to your header directory and cstream.cpp
- along with csdemo.cpp to your source directory. Compile
- csdemo.cpp and cstream.cpp and link (a project file is
- included, i.e. csdemo.prj). Run this demo and study its
- source.
-
-
- In order to make a class streamable, derive it from
- StreamableClass either publicly or privately.
-
-
- class Employee : public StreamableClass {
- ...
- public:
- StreamableClassID(Employee,StreamableClass,2);
-
- ...
-
- Employee();
- ~Employee();
- };
-
-
- The StreamableClassID macro is used to assign a unique id by
- which the class can be identified on the stream. This macro
- also declares several required member functions of which you
- must define store() and load(). Below is the macro
- definition as it appears in cstream.hpp.
-
-
- #define StreamableClassID(class, base, id) \
- public: \
- enum { CLASS_ID = id }; \
- protected: \
- base :: setID; \
- class (unsigned cid = CLASS_ID) : base (cid) \
- { return; } \
- public: \
- base :: ID; \
- operator StreamC() { return (StreamC)this; } \
- virtual void store(ostream& os); \
- static StreamC load(istream& is, StreamC C)
-
-
-
- Your store function should write out to "os" the data
- members of your class. Don't worry about the id or any
- fields in StreamableClass - this is handled automatically.
-
-
- void Employee::store(ostream& os)
- {
- os << name << endf << address << endf
- << cityStateZip << endf;
- }
-
-
- The endf manipulator outputs the end of field terminator
- which is defined as:
-
-
- char StreamableClass::FieldTermChar = '\n';
-
-
- If you decide to change it, make sure it isn't a character
- that can be interpreted as part of a number!
-
-
- Your load function should read in the data stored in the
- extact order it was written out.
-
-
- StreamC Employee::load(istream& is, StreamC C)
- {
- if (!C) if ((C = (StreamC) new Employee())
- == StreamC0)
- return C;
- is.getline(nameBuf,MAX_STR_BUF,
- StreamableClass::FieldTermChar);
- is.getline(addressBuf,MAX_STR_BUF,
- StreamableClass::FieldTermChar);
- is.getline(cityStateZipBuf,MAX_STR_BUF
- ,StreamableClass::FieldTermChar);
- ((EmployeE)C)->construct(nameBuf,addressBuf,
- cityStateZipBuf);
- return C;
- }
-
-
- If the load() function is called to load a class of this
- type, then C is NULL and load() calls the default
- constructor for your class as defined in the
- StreamableClassID() macro above. This is used simply to
- satisfy the new operator and to set the ID of the class.
- Load() can also be called from a derived class in which case
- C is not NULL! Your load function should procedure to read
- the data in, in the order stored by your store() function.
- To be consistent, all loads call the protected member
- function, construct(), which you must write, with the data
- read from the stream. Your class' regular constructor
- should typically call construct() to do the nonstream
- construction of your class. This way everybody's code using
- streamable classes will read the same.
-
-
- The trick to streamable classes is in the load() function.
- It is a static member of StreamableClass and thus has no
- implicit "this" parameter. The address of a static function
- can be taken where as the address of a constructor cannot
- be! This is why load() is declared as such. The design of
- streamable classes in C++ requires that we call a
- constructor - how else can we insure a portable way of
- initializing virtual function tables?
-
-
- Note also that load() returns "StreamC", a pointer to a
- StreamableClass base. All we know when loading a
- StreamableClass is that it is a StreamableClass. You must
- call the ID() member function, which returns the unique id
- you defined in the StreamableClassID() macro, to determine
- its class.
-
-
- If your class is not directly derived from StreamableClass,
- it still needs to use the StreamableClassID() macro.
-
-
- class Special : Product {
- ...
- void construct(...);
- ...
- public:
- StreamableClassID(Special,Product,4);
- ...
- };
-
-
- Your store() function should call the store() function of
- its immediate base class before storing its own data
- members!
-
-
- void Special::store(ostream& os)
- {
- Product::store(os);
- os << specialPrice << endf;
- }
-
-
- Likewise your load() function should call the load()
- function of its immediate base class before loading its own
- data members!
-
-
- StreamC Special::load(istream& is, StreamC C)
- {
- if (!C) if ((C = (StreamC) new Special())
- == StreamC0)
- return C;
-
- /***/ Product::load(is,C); /****/
-
- is >> spriceBuf;
- is.get(); // field term char
- ((SpeciaL)C)->construct(spriceBuf);
- return C;
- }
-
-
-
-
- You should be wondering at this point how the correct static
- load() function will be called. We need to back up first
- and see how to initialize the whole class-stream system.
- This is done by a global call to the macro
- StreamableClasses().
-
-
- StreamableClasses(20);
-
- main()
- {
-
- RegisterClass(Employee);
- RegisterClass(Product);
- RegisterClass(Special);
-
- ...
-
- StreamableClass *S1, *S2, *S3;
-
- ifstream iS("emp$prod.cls");
-
- iS >> S1 >> S2 >> S3;
-
- //S1->ID()
-
- }
-
-
- The call here initializes the system to hold a maximum of 20
- records for different streamable classes in our application.
- You should set your count appropriately.
-
- The classes to be streamed must be registered before
- attempting to stream them with a call to the macro,
- RegisterClass(). The RegisterClass() macro registers your
- class' ID and load function.
-
- When you go to read back in classes from a stream, define
- some pointers to StreamableClass and then fetch the classes
- from the stream to these pointers. To determine the actual
- class fetched, call the ID() member function.
-
-
-
- Registration
- ============
-
- If you find cstream useful and are using it in your
- applications, tell your friends. You don't need to register
- cstream -- it's freeware! All I ask is that you leave my
- copyright notice intact and to give credit where credit is
- due! How about dropping me a line (postcard or email) -- I
- always like to here your comments and suggestions. It's
- also nice to get alittle feedback and know that somebody is
- really out there!
-
-
-
- Other Freeware Goodies available for Borland C++
- =======================================================
-
-
- pckey PC keyboard class w/auto enhanced
- gconio Graphics mode conio class
- cmouse Mouse Driver class w/ intr handler
- cmdln Command line parser class
-
-
-
- And Shareware
- =============
-
-
- FlexList II ANSI && K&R C
- FlexList II C++
-
- * Ready-to-run C/C++ linked lists.
- * Hybrid structure: stack,queue,list,array.
- * Stores Heterogeneous/homogeneous data
- * Eliminates the need for parameterized list
- templates such as are proposed for
- C++ in the future.
-
-
- Loose Data Binder C++
-
- * Combination FlexList/TCollection
-
-
-
- Soon to be Released
- ===================
-
- PolyMesh II C++
-
- * Networks of Polymorphic clusters
-
-
- Something you need
- ==================
-
- Is there something you would like to see in freeware/
- shareware? Drop me a line, and I'll let you know if I have
- that something in the works.
-
-
-
- Thanks again!
-
-
- John W. Small
- CIS: 73757,2233
- Exec PC
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, VA 22102 8072
- USA (703) 759-3838
-
-
- ----------------end-of-author's-documentation---------------
-
- Software Library Information:
-
- This disk copy provided as a service of
-
- Public (software) Library
-
- We are not the authors of this program, nor are we associated
- with the author in any way other than as a distributor of the
- program in accordance with the author's terms of distribution.
-
- Please direct shareware payments and specific questions about
- this program to the author of the program, whose name appears
- elsewhere in this documentation. If you have trouble getting
- in touch with the author, we will do whatever we can to help
- you with your questions. All programs have been tested and do
- run. To report problems, please use the form that is in the
- file PROBLEM.DOC on many of our disks or in other written for-
- mat with screen printouts, if possible. PsL cannot debug pro-
- programs over the telephone, though we can answer questions.
-
- Disks in the PsL are updated monthly, so if you did not get
- this disk directly from the PsL, you should be aware that the
- files in this set may no longer be the current versions. Also,
- if you got this disk from another vendor and are having prob-
- lems, be aware that some files may have become corrupted or
- lost by that vendor. Get a current, working disk from PsL.
-
- For a copy of the latest monthly software library newsletter
- and a list of the 3,000+ disks in the library, call or write
-
- Public (software) Library
- P.O.Box 35705 - F
- Houston, TX 77235-5705
-
- Orders Only:
- 1-800-2424-PSL
- FAX: 713-524-6398
- CompuServe: 71355,470
- MC/Visa/AmEx/Discover
-
- Outside of U.S. or in Texas
- or for general information,
- Call 1-713-524-6394
-
-